package com.yybray.methodreference;

import com.yybray.Apple;
import org.junit.Test;

import java.util.*;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collectors;

/**
 * Created by Bray.ye on 2017/03/22 11:11.
 */
public class MethodReference {

    @Test
    public void name1() throws Exception {
        //方法引用主要有三累
        //方法引用可以看做是lambda表达式的语法糖
        List<String> stringList = Arrays.asList("2", "1", "3");

        //1.引用静态方法（字符转int）
        stringList.stream().map(x -> Integer.parseInt(x));
        stringList.stream().map(Integer::parseInt);

        //2.引用当前实例对应类的方法（排序）
        stringList.sort((x1, x2) -> x1.compareTo(x2));
        stringList.sort(Comparator.comparing((String s)-> s).reversed());
        stringList.sort(String::compareTo);

        //3.引用现有对象的方法（过滤列表）
        stringList.stream().filter(x -> stringList.contains("2"));
        stringList.stream().filter(stringList::contains);
    }

    @Test
    public void name2() throws Exception {
        //构造方法引用
        //1.无参构造方法引用
        Supplier<Apple> supplier = null;
        supplier = Apple::new;
        supplier = () -> new Apple();
        Apple apple = supplier.get();

        //2.有参构造方法使用
        Function<Integer, Apple> oneParamFunction = null;
        oneParamFunction = Apple::new;
        oneParamFunction = i -> new Apple(i);
        Apple apple1 = oneParamFunction.apply(110);

        BiFunction<Integer, String, Apple> twoParamFunction = null;
        twoParamFunction = Apple::new;
        twoParamFunction = (i, s) -> new Apple(i, s);
        Apple apple2 = twoParamFunction.apply(110, "red");
    }

    @Test
    public void name3() throws Exception {
        List<Apple> apples = new ArrayList<Apple>() {{
            add(new Apple(100, "green"));
            add(new Apple(150, "red"));
            add(new Apple(90, "red"));
            add(new Apple(100, "yellow"));
        }};

        List<Apple> collect = apples.stream().filter(
                ((Predicate<Apple>) (a -> a.getWeight() > 100))
                        .and(a -> a.getColor().equals("red"))
        ).collect(Collectors.toList());
        System.out.println(collect);

        Map<String, List<Apple>> collect1 = apples.stream().collect(Collectors.groupingBy(Apple::getColor));
        System.out.println(collect1);
    }
}
